/**
 * 
 */
package br.com.skynix.tcmc.seguranca;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import br.com.skynix.tcmc.model.seguranca.Usuario;
import br.com.skynix.tcmc.service.seguranca.usuarios.UsuarioService;
import br.com.skynix.tcmc.util.WebUtil;

/**
 * @author mgrb
 * 
 */
public class AutheticationFilter implements Filter {

	private UsuarioService usuarioService;

	private FilterConfig filterConfig;

	private String loginPagePath;

	private List<String> noSecuredPaths;

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	@Override
	public void destroy() {
		filterConfig = null;
		usuarioService = null;
		loginPagePath = null;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
	 * javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpResquest = ((HttpServletRequest) request);
		HttpServletResponse httpResponse = ((HttpServletResponse) response);
		String requestURI = httpResquest.getRequestURI();
		String contextPath = httpResquest.getContextPath();
		if (isrequestedPathSecured(requestURI.replaceFirst(contextPath, ""))) {
			chain.doFilter(request, response);
		}
		else {
			Usuario userSession = (Usuario) httpResquest.getSession()
					.getAttribute(WebUtil.USER_UUID);
			String loginPage = contextPath + loginPagePath;
			boolean isLoginPageRequested = requestURI.contains(loginPagePath);

			// SE Sessao de usuario não existe
			if (userSession == null) {
				// SE Pagina de login foi acessada diretamente
				if (isLoginPageRequested) {
					chain.doFilter(request, response);
				}
				else {
					httpResponse.sendRedirect(loginPage);
				}
			} // SE EXISTE Sessao de usuario, esta sessao tem que ser a versao
				// atual
			else if (userSession.getVersao().equals(
					usuarioService.getVersaoAtual(userSession.getId()))) {
				// SE pagina de login for requisitada diretamente com a sessão
				// de
				// usuario valida redirecione para a pagina principal (HOME)
				if (isLoginPageRequested) {
					httpResponse.sendRedirect(contextPath);
				}
				else {
					chain.doFilter(request, response);
				}
			} // SE a sessao de usuario não for a mais recente redirecione para
				// a
				// tela de login
			else {
				httpResponse.sendRedirect(loginPage);
			}
		}
	}

	/**
	 * @param requestURI
	 * @return
	 */
	private boolean isrequestedPathSecured(String requestURI) {
		for (String noSecuredPath : noSecuredPaths) {
			if (requestURI.startsWith(noSecuredPath)) {
				return true;
			}
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
		usuarioService = (UsuarioService) WebUtil.lookUpService(
				UsuarioService.class, filterConfig.getServletContext());
		loginPagePath = filterConfig.getInitParameter("login_page_path");
		noSecuredPaths = getNoSecuredPaths(filterConfig
				.getInitParameter("no_security_path"));
	}

	/**
	 * @param initParameter
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private List<String> getNoSecuredPaths(String initParameter) {
		return initParameter == null ? Collections.EMPTY_LIST : Arrays
				.asList(initParameter.split(";"));
	}

}
